package com.example.winwallpaper.component;

import lombok.extern.slf4j.Slf4j;
import org.apache.tika.Tika;
import org.apache.tika.mime.MediaType;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

/**
 * @author fangyuan.xia
 * @since 2023-05-22
 */
@Service
@Slf4j
public class WallPaperExecutor {

    @Bean
    public CommandLineRunner commandLineRunner(@Value("${dir_input}") String dirInput, @Value("${dir_output}") String dirOutput) {
        return args -> {

            log.info("commandLineRunner dirInput={}\ndirOutput={}", dirInput, dirOutput);
            String absWinDirInput = absoluteWinPath(dirInput);
            String absWinDirOutput = absoluteWinPath(dirOutput);
            log.info("commandLineRunner absWinDirInput={}\nabsWinDirOutput={}", absWinDirInput, absWinDirOutput);

            Path inputDir = Paths.get(absWinDirInput);
            Path outputDir = Paths.get(absWinDirOutput);
            Tika tika = new Tika();
            try (Stream<Path> pathStream = Files.list(inputDir)) {
                pathStream.forEach(p -> {
                    MediaType mediaType;
                    try {
                        long size = Files.size(p);
                        // 小于100KB，可能为图标跳过，硬盘上使用1000作为进制而非1024
                        if (size < 100_000) {
                            log.info("commandLineRunner skip {}", p.toAbsolutePath());
                            return;
                        }
                        String mimeType = tika.detect(p);
                        mediaType = MediaType.parse(mimeType);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                    if (mediaType != null) {
                        String subtype = mediaType.getSubtype();
                        Path newPath = outputDir.resolve(p.getFileName() + "." + subtype);
                        if (!Files.exists(newPath)) {
                            try {
                                Files.copy(p, newPath);
                                log.info("commandLineRunner copyTo newPath={}", newPath);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }
                });
            }
        };
    }

    /**
     * 将带有占位符的win路径转换为绝对路径，例如 "%localappdata%"
     *
     * @param winPath windows 路径
     * @return windows 绝对路径
     */
    private String absoluteWinPath(String winPath) {
        Pattern pattern = Pattern.compile("%(.*?)%");
        Matcher matcher = pattern.matcher(winPath);
        StringBuilder sb = new StringBuilder();
        while (matcher.find()) {
            String group = matcher.group(1);
            log.info("loopReplacement placeholder={}", group);
            String env = System.getenv(group);// 从环境变量中获取指向的真实内容
            env = env.replaceAll("\\\\", "\\\\\\\\");
            log.info("loopReplacement actual path={}", env);
            matcher.appendReplacement(sb, env);

        }
        matcher.appendTail(sb);
        log.info("loopReplacement absoluteWinPath={}", sb);
        return sb.toString();
    }
}
